package com.um.swing.dialog;

import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.util.StrUtil;
import com.um.swing.MainView;
import com.um.swing.bean.ImageItem;
import com.um.swing.common.util.MessageUtil;
import com.um.swing.common.util.VersionUtil;
import com.um.swing.common.util.WindowUtil;
import com.um.swing.core.thread.ExportManageRunable;
import com.um.swing.http.HttpVersionApi;
import com.um.swing.http.bean.Version;
import com.um.swing.http.callback.HttpCallback;
import com.um.swing.common.inc.Constant;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.TimerTask;


/**
 * 名称：检测更新弹窗
 * 创建人：袁泉
 * 创建时间：2022年05月08日17:26:06
 */
public class JUpdateDialog extends JDialog {

    private static final long serialVersionUID = 2914192200129777056L;

    public static final Dimension W_SIZE = new Dimension(550, 180);

    private List<ImageItem> mList;//需要导出的数据集

    private JProgressBar jProgressBar;//进度条组件
    private JLabel jLabel;//状态信息
    private JButton jUpdateLogBtn, jTryUpdateBtn, jInstallBtn;//操作按钮


    private String mStrTemplate = "<html> 当前版本：{}    最新版本：{}<br/><br/>{}</html>";
    private int mCurrentProgress = 0;
    private boolean isExportIng = false;//是否正在导出
    private File mTargetFile;//导出到目标目录
    private ExportManageRunable mManageRunable;//导出-任务对象

    private boolean mIsForceVersion = false;//是否强制更新版本

    private HttpVersionApi versionApi = HttpVersionApi.getInstance();
    private Version mTargetVersion;

    private static JUpdateDialog __instance = null;

    public static JUpdateDialog getInstance() {
        if (__instance == null)
            __instance = new JUpdateDialog();
        return __instance;
    }

    private JUpdateDialog() {
        super(new Frame());
        WindowUtil.setIcon(this, null);

        this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        setTitle(Constant.W_TITLE + " 更新");
        setPreferredSize(W_SIZE);
        setSize(W_SIZE);
        setLocationRelativeTo(null);
        setVisible(false);
        jProgressBar = new JProgressBar(SwingConstants.HORIZONTAL, 0, 100);
        // 绘制百分比文本（进度条中间显示的百分数）
        Box vBox = Box.createVerticalBox();
        jProgressBar.setStringPainted(true);
        jProgressBar.setString("准备处理中");
        jProgressBar.setPreferredSize(new Dimension((int) W_SIZE.getWidth() - 20, 20));
        //操作按钮
        vBox.add(jProgressBar);
        JPanel statusPanel = new JPanel(new BorderLayout());
        String str = StrUtil.format(mStrTemplate, Constant.VERSION, "获取中", "已经是最新版");
        jLabel = new JLabel(str, JLabel.CENTER);

        statusPanel.add(jLabel, BorderLayout.CENTER);
        statusPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
        vBox.add(statusPanel);
        //操作按钮
        JPanel optPanel = new JPanel(new BorderLayout());
        jUpdateLogBtn = new JButton("更新日志");
        jTryUpdateBtn = new JButton("检查更新");
        jInstallBtn = new JButton("开始更新");
        jUpdateLogBtn.setEnabled(false);
        jInstallBtn.setEnabled(false);
        JPanel btnWarp = new JPanel(new FlowLayout());
        btnWarp.add(jUpdateLogBtn);
        btnWarp.add(jTryUpdateBtn);
        btnWarp.add(jInstallBtn);
        optPanel.add(btnWarp, BorderLayout.CENTER);
        optPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
        vBox.add(optPanel);

        vBox.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        this.add(vBox, BorderLayout.NORTH);
        jProgressBar.updateUI();

        bindEvent();
    }

    private void bindEvent() {
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                if (mIsForceVersion) {
                    int btn = MessageUtil.confirm(__instance, "发现新版本，该版本为强制更新，关闭更新窗口将直接退出程序");
                    if (btn == 0) {
                        System.exit(0);
                    } else {
                        return;
                    }
                }
                __instance.setVisible(false);
            }
        });

        //检测更新
        jTryUpdateBtn.addActionListener(t -> tryUpdateInfo(false));

        //开始更新按钮
        jInstallBtn.addActionListener(t -> {
            downloadPackage();
        });
    }

    private void downloadPackage() {
        String downloadUrl = mTargetVersion.getDownloadUrl();
        String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
        String targetPath = this.getClass().getResource("/").getPath() + "update" + File.separator + fileName;
        versionApi.download(mTargetVersion, targetPath, new StreamProgress() {
            @Override
            public void start() {
                SwingUtilities.invokeLater(() -> {
                    jProgressBar.setValue(0);
                    jProgressBar.updateUI();
                    jProgressBar.setString("正在校验文件");
                    btnEnabled(false);
                });
            }

            @Override
            public void progress(long total, long progressSize) {
                updateProgress(total, progressSize);
            }

            @Override
            public void finish() {
                int btn = MessageUtil.confirm(__instance, "安装包已经下载完成，是否进行安装？");
                if (btn == 0) {
                    installPackage(targetPath);
                }
                btnEnabled(true);
            }
        });
    }

    //检测版本
    public void tryUpdateInfo(boolean isBackground) {
        String text = StrUtil.format(mStrTemplate, Constant.VERSION, "正在获取最新版本...", "");
        jLabel.setText(text);
        jTryUpdateBtn.setEnabled(false);
        versionApi.findNewVersion(new HttpCallback<Version>() {
            @Override
            public void onOk(Version data) {
                String msg = "";
                if (Constant.VERSION.equals(data.getVersion())) {
                    msg = "已经是最新版本，无需更新";
                } else {
                    mTargetVersion = data;
                    jInstallBtn.setEnabled(true);

                    msg = StrUtil.format("发现最新版本:{}，请尽快更新至最新版本", data.getVersion());
                    if (data.isForce() || VersionUtil.compareVersion(Constant.VERSION, data.getMiniVersion()) == 2) {
                        mIsForceVersion = true;
                        MainView.getInstance().setVisible(false);
                        if (isBackground) {
                            __instance.setVisible(true);
                        }
                    }
                }
                String text = StrUtil.format(mStrTemplate, Constant.VERSION, data.getVersion(), msg);
                jLabel.setText(text);
                jTryUpdateBtn.setEnabled(true);
                if (mTargetVersion != null && isBackground) {
                    int btn = MessageUtil.confirm(__instance, msg);
                    if (btn != 0) {
                        return;
                    }
                    __instance.setVisible(true);
                    downloadPackage();
                }
            }

            @Override
            public void onFail(String msg) {
                jTryUpdateBtn.setEnabled(true);
                jLabel.setText("获取最新版本失败:" + msg);
                MainView mainView = MainView.getInstance();
                mainView.setVisible(false);
                MessageUtil.alert(mainView, "该版本已被禁止使用");
                System.exit(0);
            }
        });
    }

    //更新下载进度
    private void updateProgress(long total, long progressSize) {
        if (jProgressBar.getMaximum() != total) {
            jProgressBar.setMaximum((int) total);
        }
        SwingUtilities.invokeLater(() -> {
            jProgressBar.setValue((int) progressSize);
            jProgressBar.updateUI();
            jProgressBar.setString(String.format("%.2f", (progressSize / Double.valueOf(total)) * 100) + "%");
        });
    }


    //安装新版程序
    private void installPackage(String targetPath) {
        //运行安装包
        Runtime ec = Runtime.getRuntime();
        File installFile = new File(targetPath);
        File file = new File(installFile.getParentFile().getPath(), installFile.getName());
        new java.util.Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    ec.exec(file.getAbsolutePath());
                    System.exit(0);
                } catch (IOException e) {
                    btnEnabled(true);
                    MessageUtil.alert(__instance, "运行安装包失败，请手动运行安装包进行安装");
                    try {
                        Desktop.getDesktop().open(file.getParentFile());
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    e.printStackTrace();
                }
            }
        }, 888);
    }

    private void btnEnabled(boolean enabled) {
        SwingUtilities.invokeLater(() -> {
            jTryUpdateBtn.setEnabled(enabled);
            jInstallBtn.setEnabled(enabled);
        });
    }
}
